package com.ks.controller;

import com.ks.entity.SysRole;
import com.ks.entity.SysUser;
import com.ks.repository.SysUserRepository;
import com.ks.utils.JwtTokenUtil;
import com.ks.utils.Result;
import io.swagger.annotations.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 授权相关
 *
 * @author kuShao <kushaobuy@163.com>
 * @version 2017/4/28
 */
@RestController
@Api(tags = "Auth", value = "Auth", description = "用户授权与注销")
public class AuthController {
    @Autowired
    private AuthenticationManager authenticationManager;
    @Autowired
    private UserDetailsService userDetailsService;
    @Autowired
    private JwtTokenUtil jwtTokenUtil;
    @Autowired
    private SysUserRepository sysUserRepository;

    @Value("${jwt.header}")
    private String tokenHeader;

    @Value("${jwt.tokenHead}")
    private String tokenHead;

    @ApiOperation(value="用户授权")
    @RequestMapping(value = "/auth", method = RequestMethod.POST, consumes = "application/json",
            produces = "application/json;charset=UTF-8")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户信息", required = true, paramType = "body", dataType = "SysUser"),
    })
    public Result login(@RequestBody SysUser user){

        String username = user.getUsername();
        String password = user.getPassword();

        UsernamePasswordAuthenticationToken upToken = new UsernamePasswordAuthenticationToken(username, password);

        final Authentication authentication = authenticationManager.authenticate(upToken);
        SecurityContextHolder.getContext().setAuthentication(authentication);

        final UserDetails userDetails = userDetailsService.loadUserByUsername(username);
        final String token = jwtTokenUtil.generateToken(userDetails);

        return Result.fillResult(true, token, token);
//        return token;
    }

    @ApiOperation(value = "重新获取token")
    @RequestMapping(value = "/refresh",  method = RequestMethod.GET)
    public Result refresh(HttpServletRequest request) throws AuthenticationException {
        String oldToken = request.getHeader(tokenHeader);
        String refreshedToken = null;

        final String token = oldToken.substring(tokenHead.length());
        String username = jwtTokenUtil.getUsernameFromToken(token);
        SysUser user = (SysUser) userDetailsService.loadUserByUsername(username);

        if (jwtTokenUtil.canTokenBeRefreshed(token, user.getLastPasswordResetDate())){
            refreshedToken = jwtTokenUtil.refreshToken(token);
        }

        if(refreshedToken == null) {
            return Result.fillResult(false, "旧token已经过期", null);
        }

        return Result.fillResult(true, refreshedToken, refreshedToken);
    }

    @ApiOperation(value = "注册普通用户, user 角色")
    @RequestMapping(value = "/register", method = RequestMethod.POST, consumes = "application/json",
            produces = "application/json;charset=UTF-8")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "user", value = "用户信息", required = true, paramType = "body", dataType = "SysUser"),
    })
    public Result register(@RequestBody SysUser user){

        final String username = user.getUsername();
        if(sysUserRepository.findByUsername(username)!=null) {
            return null;
        }
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        final String rawPassword = user.getPassword();
        user.setPassword(encoder.encode(rawPassword));
        user.setLastPasswordResetDate(new Date());
        List<SysRole> roles = new ArrayList<SysRole>();
        SysRole role = new SysRole();
        role.setId(new Long(2));
        role.setName("user");
        roles.add(role);
        user.setRoles(roles);
        sysUserRepository.save(user);

        return Result.fillResult(true, "", user);
    }
}
